﻿/*  
 Copyright 2010 The 'Tribe.Blog' development team  
 (http://tribecache.codeplex.com/team/view)

 This library is licensed under the Ms-PL Microsoft Public License.  You should 
 have received a copy of the license along with the source code.  If not, an online copy
 of the license can be found at http://tribecache.codeplex.com/license.
 
 http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx
 
*/

using System.Threading;

namespace Tribe.Cache.Threading
{
    ///<summary>
    /// Lock Wrapper
    ///</summary>
    internal static class Lock
    {
        /// <summary>
        /// Aquires a read lock
        /// </summary>
        /// <param name="readerWriterLockSlim"></param>
        internal static void GetReadLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            bool lockAcquired = false;
            while (!lockAcquired)
                lockAcquired = readerWriterLockSlim.TryEnterUpgradeableReadLock(1);
        }
        /// <summary>
        /// Aquires a read only lock
        /// </summary>
        /// <param name="readerWriterLockSlim"></param>
        internal static void GetReadOnlyLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            bool lockAcquired = false;
            while (!lockAcquired)
                lockAcquired = readerWriterLockSlim.TryEnterReadLock(1);
        }
        /// <summary>
        /// Aquires a write lock
        /// </summary>
        /// <param name="readerWriterLockSlim"></param>
        internal static void GetWriteLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            bool lockAcquired = false;
            while (!lockAcquired)
                lockAcquired = readerWriterLockSlim.TryEnterWriteLock(1);
        }
        /// <summary>
        /// Releases a read only lock
        /// </summary>
        /// <param name="readerWriterLockSlim"></param>
        internal static void ReleaseReadOnlyLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            if (readerWriterLockSlim.IsReadLockHeld)
                readerWriterLockSlim.ExitReadLock();
        }
        ///<summary>
        /// Releases a read lock
        ///</summary>
        ///<param name="readerWriterLockSlim"></param>
        internal static void ReleaseReadLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            if (readerWriterLockSlim.IsUpgradeableReadLockHeld)
                readerWriterLockSlim.ExitUpgradeableReadLock();
        }
        ///<summary>
        /// Releases a write lock
        ///</summary>
        ///<param name="readerWriterLockSlim"></param>
        internal static void ReleaseWriteLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            if (readerWriterLockSlim.IsWriteLockHeld)
                readerWriterLockSlim.ExitWriteLock();
        }
        ///<summary>
        /// Release locks - Write / Read / ReadOnly
        ///</summary>
        ///<param name="readerWriterLockSlim"></param>
        internal static void ReleaseLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            ReleaseWriteLock(readerWriterLockSlim);
            ReleaseReadLock(readerWriterLockSlim);
            ReleaseReadOnlyLock(readerWriterLockSlim);
        }
        ///<summary>
        /// Gets the lock instance
        ///</summary>
        ///<returns></returns>
        internal static ReaderWriterLockSlim GetLockInstance()
        {
            return GetLockInstance(LockRecursionPolicy.SupportsRecursion);
        }
        /// <summary>
        /// Gets the lock instance with LockRecursionPolicy
        /// </summary>
        /// <param name="recursionPolicy"></param>
        /// <returns></returns>
        internal static ReaderWriterLockSlim GetLockInstance(LockRecursionPolicy recursionPolicy)
        {
            return new ReaderWriterLockSlim(recursionPolicy);
        }
    }
}